/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package encaps.utils;

import encaps.action.Action;
import encaps.action.ActionFactory;
import encaps.entities.Grant;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;


public class RequestParser {

    private String defaultActionFactory = "viewProfile";

    private Map<String, ActionFactory> actionFactories;

    public RequestParser() {
        actionFactories = new HashMap<String, ActionFactory>();

        try {
            //Загружаем xml-файл как ресурс
            Class c = getClass();
            InputStream in = c.getResourceAsStream("/encaps/resources/actionFactories.xml");

            //Парсим xml-файл
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(in);

            Element root = doc.getRootElement();

            //Установка фабрики по умолчанию
            Element defaultFactoryElement = root.getChild("default-factory");
            defaultActionFactory =
                    defaultFactoryElement.getChild("name").getValue().trim();

            //Заполнение карты фабрик
            List factories = root.getChild("factory-list").getChildren("factory");
            for(Object obj: factories) {
                Element factoryElement = (Element) obj;
                String name = factoryElement.getChild("name").getValue().trim();
                String className = factoryElement.getChild("class").getValue().trim();
                String requiredGrantName = factoryElement.getChild("grant").getValue().trim();

                //Создаем экземпляр фабрики Action-ов
                Class factoryClass = Class.forName(className);
                Constructor constructor = factoryClass.getConstructor(Grant.class);
                ActionFactory factory = (ActionFactory) constructor.newInstance(new Grant(requiredGrantName));
                //ActionFactory factory = (ActionFactory) factoryClass.newInstance();

                //Добавляем фабрику в карту
                actionFactories.put(name, factory);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RequestParserException("Cannot create Request Parser: " + ex.getMessage(), ex);
        }
    }

    public Map getMap() {
        return actionFactories;
    }

    public String getDefaultActionFactory() {
        return defaultActionFactory;
    }

    public Action parseRequest(String actionName, Map parameters) {
        if(StringUtil.isEmpty(actionName)) {
            actionName = defaultActionFactory;
        }
        ActionFactory factory = actionFactories.get(actionName);
        Action action = factory.createAction(parameters);
        return action;
    }
}
